package com.daqsoft.socket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.daqsoft.dto.MessageTypeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 周麟东 on 14:51
 */
@ServerEndpoint("/socket")
@Component
public class UserWebSocket {
    private Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 在线用户
     * key 为在线用户的id , value为对话对象
     */
    private static Map<Integer, Session> ONLINE_USERS = new HashMap<>();

    private Session session;
    @OnOpen
    public void onOpen(Session session){
        //用户建立socket链接的方法
        this.session = session;
    }

    /**
     * 消息接受器
     * @param msg 消息内容 以Json Fromat的字符串 消息协议格式为
     *            {
     *              userId:用户ID int
     *              type: 消息类型 : @see com.daqsoft.dto.MessageTypeEnum
     *              msg:消息内容 string 或者 jsonString
     *            }
     * @see com.daqsoft.dto.MessageTypeEnum
     * @param session 对话对象
     */
    @OnMessage
    public void onMessage(String msg , Session session){
        JSONObject jsonObject = JSON.parseObject(msg);
        if (MessageTypeEnum.valueOf(jsonObject.getString("type")) == MessageTypeEnum.LOGIN){
            //注册用户信息 用户在完成登录后就需要注册
            int userId = jsonObject.getInteger("userId");
            //注册到对话
            ONLINE_USERS.put(userId,session);
            log.info("用户[{}]注册websocket成功 ",userId);
        }
    }

    @OnClose
    public void onClose(){
        //删除
        for (Integer integer : ONLINE_USERS.keySet()) {
            Session s = ONLINE_USERS.get(integer);
            if (s.getId().equals(this.session.getId())){
                ONLINE_USERS.remove(integer);
                log.info("用户[{}]已断开连接",integer);
                break;
            }
        }
    }

    /**
     * 向用户发送消息
     *
     * 如果返回false则用户没有发送成功 需要额外处理
     */
    public boolean sendMessage(String msg , int userId){
        Session session =  ONLINE_USERS.get(userId);
        if (session == null){
            return false;
        }
        try {
            session.getBasicRemote().sendText(msg);
        } catch (IOException e) {
            return false;
        }
        return true;
    }
}
